import os
from threading import Thread
from time import sleep, time_ns
import serial
import json

class Downloader(object):
    def __init__(self, config) -> None:
        self.config = config

        com = config.get('port')
        speed = config.get('speed')

        print(speed)
        self.serialport = serial.Serial(com, speed[0], timeout=60)
        self.rx_thread = Thread(target=self.serial_rx_handler, args=(self, ))
        # 启动接收线程
        self.rx_thread.start()

    def serial_rx_handler(self, name):
        while True:
            if self.serialport.in_waiting > 0:
                recv_bytes = self.serialport.read(self.serialport.in_waiting)
                self.serial_received(recv_bytes)

    def toHexString(self, src = [], format = '0x{:02X}') -> str:

        if type(src) is not list:
            raise TypeError('not a list of int')
        
        if src == None or src == []:
            return ''
        else:
            return (' '.join(map(lambda a:format.format(a), src))).rstrip()

    def serial_received(self, data):
        pass

    def download(self) -> bool:
        return False
    
class Stc_Downloader(Downloader):
    def __init__(self, config) -> None:
        super().__init__(config)
        self.pkg = []
        self.data_pkts = []

    def serial_received(self, data):
        self.pkg.extend(data)
        pkg_len = len(self.pkg)
        if self.pkg[-1] == 0x16:
            print(self.toHexString(self.pkg))
        # if pkg_len > 5:
        #     head = 0
        #     for i in range(pkg_len):
        #         if self.pkg[i] == 0x46:
        #             head = i
        #             break
        #     self.pkg = self.pkg[head:]
        #     if len(self.pkg) < 7:
        #         return
        #     if self.pkg[0] == 0x46 and self.pkg[1] == 0xB9 and self.pkg[2] == 0x68:
        #         data_len = (self.pkg[3]<<8) | self.pkg[4]
        #         if len(self.pkg) >= data_len + 5:
        #             # print(self.toHexString(self.pkg))
        #             subpkt = self.pkg[:data_len+5]
        #             print(self.toHexString(subpkt))
        #             if subpkt[-1] == 0x16:
        #                 self.data_pkts.append(subpkt)
        #             self.pkg.clear()
        #         elif self.pkg[-1] == 0x16:
        #             print(self.toHexString(self.pkg))
        #             self.pkg.clear()

    def handshark(self) -> bool:
        while True:
            self.serialport.write([0x7F])
            sleep(0.012)
            for pkt in self.data_pkts:
                if pkt[5] == 0x50:
                    return True
        return False

    def download(self) -> bool:
        if self.handshark():
            print('handshark')
        else:
            return False
        
        self.serialport.write([0x46, 0xB9, 0x6A, 0x00, 0x0D, 0x50, 0x00, 0x00, 0x36, 0x01, 0xD1, 0x7E, 0x02, 0x4D, 0x16])
        print('waitting 0x8F')
        while True:
            flag = False
            for pkt in self.data_pkts:
                if pkt[2] == 0x68 and pkt[5] == 0x8F:
                    flag = True
            if flag:
                break

        return False
    
class STM32_Downloader(Downloader):
    def __init__(self, config) -> None:
        super().__init__(config)

        self.buffer = []

    def serial_received(self, data):
        self.buffer.extend(data)
        print(self.toHexString(self.buffer))

    def download(self) -> bool:
        return super().download()

if __name__ == '__main__':
    json_path = 'D:\wxj\easy\json\stc.json'

    with open(json_path, 'r') as f:
        config = json.load(f)

    downloader = Stc_Downloader(config)
    downloader.download()

